package com.dycloud.project.filter;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;


/**
 * Repeatable 过滤器
 *
 * @author dycloud
 */
@Slf4j
@Component
public class RepeatableFilter implements Filter {

    @Value("${log.enabled}")
    private boolean enabled;


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        long startTime = System.currentTimeMillis();

        ServletRequest requestWrapper = request;

        if (request instanceof HttpServletRequest httpRequest
                && !(request instanceof RepeatedlyRequestWrapper)) {

            String contentType = httpRequest.getContentType();
            boolean isMultipart = contentType != null && contentType.toLowerCase().contains("multipart");

            if (!isMultipart) {
                requestWrapper = new RepeatedlyRequestWrapper(httpRequest, response);
            }
        }

        try {
            chain.doFilter(requestWrapper, response);
        } finally {
            if (enabled) {
                long duration = System.currentTimeMillis() - startTime;
                if (requestWrapper instanceof RepeatedlyRequestWrapper) {
                    RepeatedlyRequestWrapper wrapper = (RepeatedlyRequestWrapper) requestWrapper;
                    HttpServletRequest httpServletRequest = (HttpServletRequest) requestWrapper;

                    String uri = httpServletRequest.getRequestURI();
                    String method = httpServletRequest.getMethod();

                    String body = wrapper.getBody();
                    if (StringUtils.isNotBlank(body) && isJson(body)) {
                        //   log.info("[请求方法]:{} [请求地址]: {} | [耗时]: {} ms [请求体]: {}", method, uri, duration, body);
                        log.info("[请求日志]\n" +
                                        "\u001B[32m▣ 方法: \u001B[33m{}\u001B[0m\n" +
                                        "\u001B[32m▣ 地址: \u001B[34m{}\u001B[0m\n" +
                                        "\u001B[32m▣ 耗时: \u001B[35m{}ms\u001B[0m\n" +
                                        "\u001B[32m▣ 内容: \u001B[36m{}\u001B[0m\n" +
                                        "\u001B[36m┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄",
                                method, uri, duration, body);
                    } else {
                        // log.info("[请求方法]:{} [请求地址]: {} | [耗时]: {} ms", method, uri, duration);
                        log.info("[请求日志]\n" +
                                        "\u001B[32m▣ 方法: \u001B[33m{}\u001B[0m\n" +
                                        "\u001B[32m▣ 地址: \u001B[34m{}\u001B[0m\n" +
                                        "\u001B[32m▣ 耗时: \u001B[35m{}ms\u001B[0m\n" +
                                        "\u001B[36m┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄",
                                method, uri, duration);
                    }
                } else if (request instanceof HttpServletRequest httpServletRequest) {
                    log.info("[请求日志] {} {} | 耗时: {} ms (multipart/form-data 或其他请求)", httpServletRequest.getMethod(),
                            httpServletRequest.getRequestURI(), duration);
                }
            }
        }
    }

    @Override
    public void destroy() {

    }

    private boolean isJson(String body) {
        return body.trim().startsWith("{") || body.trim().startsWith("[");
    }
}
